cmake_minimum_required(VERSION 3.22)

project(netlib VERSION 1.0.0)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

if(NOT CMAKE_BUILD_TYPE)
	set(CMAKE_BUILD_TYPE Debug)
endif()
set(LIB_BUILD_TYPE ${CMAKE_BUILD_TYPE})

# Set output directory
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)

message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
message(STATUS "CXX standard: C++${CMAKE_CXX_STANDARD}")

########################################################################
### ExternalProject
########################################################################
include(ExternalProject)

set_property(DIRECTORY PROPERTY EP_BASE ${PROJECT_SOURCE_DIR}/third_party)
set(STAGED_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}/deps)

ExternalProject_Add(gtest
  URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.tar.gz
  URL_HASH MD5=c8340a482851ef6a3fe618a082304cfc
  DOWNLOAD_NO_PROGRESS 1
  UPDATE_COMMAND ""
  LOG_CONFIGURE 1
  LOG_BUILD 1
  LOG_INSTALL 1
  BUILD_ALWAYS 1
  CMAKE_ARGS
    -DCMAKE_INSTALL_PREFIX=${STAGED_INSTALL_PREFIX}
    -DCMAKE_BUILD_TYPE=${LIB_BUILD_TYPE}
    -DGFLAGS_NAMESPACE=gflags
    -DBUILD_STATIC_LIBS=ON
    -DBUILD_SHARED_LIBS=OFF
  BUILD_COMMAND make -j${CPU_CORE}
)
ExternalProject_Add(protobuf
  URL https://github.com/protocolbuffers/protobuf/releases/download/v3.17.3/protobuf-cpp-3.17.3.tar.gz
  URL_HASH MD5=3fe4c2647e0991c014a386a896d0a116
  DOWNLOAD_NO_PROGRESS 1
  UPDATE_COMMAND ""
  LOG_CONFIGURE 1
  LOG_BUILD 1
  LOG_INSTALL 1
  SOURCE_SUBDIR cmake
  CMAKE_ARGS
    -DCMAKE_INSTALL_PREFIX=${STAGED_INSTALL_PREFIX}
    -DCMAKE_BUILD_TYPE=${LIB_BUILD_TYPE}
    -DBUILD_SHARED_LIBS=FALSE
    -Dprotobuf_BUILD_TESTS=FALSE
  BUILD_IN_SOURCE 1
  BUILD_ALWAYS 1
  BUILD_COMMAND make -j${CPU_CORE}
)
if(${LIB_BUILD_TYPE} STREQUAL Debug)
  set(PROTOBUF_LIB libprotobufd.a)
else()
  set(PROTOBUF_LIB libprotobuf.a)
endif()
set(PROTOBUF_PROTOC ${STAGED_INSTALL_PREFIX}/bin/protoc)

########################################################################
### 
########################################################################
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)

include_directories(
  PUBLIC ${PROJECT_SOURCE_DIR}/include
  PRIVATE ${STAGED_INSTALL_PREFIX}/include
)

add_subdirectory(src/base)
add_subdirectory(src/net)
add_subdirectory(src/rpc)
add_subdirectory(tests)
if (BUILD_EXAMPLES)
  add_subdirectory(examples)
endif()

########################################################################
### CustomTarget
########################################################################
set(BUILD_SUPPORT_DIR ${PROJECT_SOURCE_DIR}/build_support)

string(CONCAT NETLIB_FORMAT_DIRS
  "${PROJECT_SOURCE_DIR}/src,"
  "${PROJECT_SOURCE_DIR}/include,"
  "${PROJECT_SOURCE_DIR}/examples,"
  "${PROJECT_SOURCE_DIR}/tests,"
)

add_custom_target(format
  COMMAND ${BUILD_SUPPORT_DIR}/run_clang_format.py
  /usr/bin/clang-format
  ${BUILD_SUPPORT_DIR}/clang_format_exclusions.txt
  --source_dirs ${NETLIB_FORMAT_DIRS}
  --quiet
  --fix
)

add_custom_target(clang-tidy
  COMMAND ${BUILD_SUPPORT_DIR}/run_clang_tidy.py
    -clang-tidy-binary /usr/bin/clang-tidy
    -p ${CMAKE_BINARY_DIR}
    -extra-arg=-std=c++17
  WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)


add_custom_target(clang-tidy-fix 
  COMMAND ${BUILD_SUPPORT_DIR}/run_clang_tidy.py
  -clang-tidy-binary /usr/bin/clang-tidy
  -p ${CMAKE_BINARY_DIR}
  -extra-arg=-std=c++17
  -fix
)

file(GLOB_RECURSE NETLIB_LINT_FILES
  "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h"
  "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp"
  "${CMAKE_CURRENT_SOURCE_DIR}/tests/*.h"
  "${CMAKE_CURRENT_SOURCE_DIR}/tests/*.cpp"
)

add_custom_target(cpplint echo '${NETLIB_LINT_FILES}' | xargs -n12 -P8
  ${CPPLINT_BIN}
  --verbose=2 --quiet
  --linelength=120
  --filter=-legal/copyright,-build/header_guard,-runtime/references
)
